﻿/*---------------------------------------------------------------- 
// author：zhanghaijun
// 时间：2017/10/17
//----------------------------------------------------------------*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using Utility;
using System.Text.RegularExpressions;
using System.Threading;

namespace translate
{
    public partial class Form1 : Form
    {
        public class lineStruct
        {
            public string lineWord = "";
            public int line = 0;
            public string lineAll = "";
        }

        public class pageStruct
        {
            public string pageName = "";
            public string pagePath = "";
            public List<lineStruct> content = new List<lineStruct>();
        }
        private bool isContinueWriteExcel = false;
        private string checkPath = "";
//        private string checkPath = "E:\\Game\\LastFight\\Client\\Assets";
//        private string checkPath = "D:\\PerspectivePro\\最后一战\\Client\\Assets\\Scripts";

        //       private string checkPath = "D:\\Work\\front\\crossgate\\Assets";
        private string savePath = "out.xlsx";
        private StringBuilder wordListBuilder = new StringBuilder("");
        private int selectLanguage = 0;
        private bool conditionCsharp = false;
        private bool conditionJava = false;
        private bool conditionLua = false;
        private bool conditionPython = false;
        private bool conditionC = false;
        private bool conditionCpp = false;
        private bool conditionH = false;
        private bool conditionHpp = false;
        private bool conditionM = false;
        private bool conditionMM = false;

        private List<pageStruct> pageList = new List<pageStruct>();
        private List<lineStruct> _data = new List<lineStruct>();
        private string translateLanguage = "";

        private delegate int IntMethod();
        private GoogleTranslateTool googleTranslate = new GoogleTranslateTool();
        private string iniFileName = "translation.ini";
        private Thread objThread;

        public Form1()
        {
            InitializeComponent();
            //googleTranslate.GoogleTranslate("RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.This parameter can be any combination of the following values", "auto", "zh-CN");
            init();
        }

        private void init()
        {
            string foldPath = System.Environment.CurrentDirectory;
            InputTextBox.Text = foldPath;
            OutTextBox.Text = foldPath + savePath;
            savePath = foldPath + savePath;

            SelectlanguageComboBox.SelectedIndex = 0;
            SelecltLanguagePanel.Visible = false;

            SelectTranslateComboBox.SelectedIndex = 0;

            EventCenter.AddListener(EGameEvent.eBackMainWindow, ShowSelf);
            ReadIni();
        }

        private void ReadIni()
        {
            IniFiles iniFile = new IniFiles(iniFileName);
            System.Collections.Specialized.NameValueCollection nameValueCol = new System.Collections.Specialized.NameValueCollection();
            iniFile.ReadSectionValues("CodeLanguage", nameValueCol);
            if (nameValueCol.Count > 0)
                SelectlanguageComboBox.Items.Clear();
            for (int i = 0; i < nameValueCol.Count; i++)
            {
                SelectlanguageComboBox.Items.Add(nameValueCol.Get(i));
            }
            SelectlanguageComboBox.SelectedIndex = 0;
            nameValueCol = new System.Collections.Specialized.NameValueCollection();
            iniFile.ReadSectionValues("TranslateLanguage", nameValueCol);

            if (nameValueCol.Count > 0)
                SelectTranslateComboBox.Items.Clear();
            for (int i = 0; i < nameValueCol.Count; i++)
            {
                SelectTranslateComboBox.Items.Add(nameValueCol.Get(i));
            }
            SelectTranslateComboBox.SelectedIndex = 0;
            nameValueCol = new System.Collections.Specialized.NameValueCollection();
            iniFile.ReadSectionValues("CodeLanguageSymbol", nameValueCol);
            Tools.codeLanguageSymbol.Clear();
            if (nameValueCol.Count > 0)
                Tools.codeLanguageSymbol.Clear();
            for (int i = 0; i < nameValueCol.Count; i++)
            {
                Tools.codeLanguageSymbol.Add(nameValueCol.Get(i));
            }

            nameValueCol = new System.Collections.Specialized.NameValueCollection();
            iniFile.ReadSectionValues("TranslateLanguage", nameValueCol);
            Tools.languageSymbol.Clear();
            if (nameValueCol.Count > 0)
                Tools.languageSymbol.Clear();
            for (int i = 0; i < nameValueCol.Count; i++)
            {
                Tools.languageSymbol.Add(nameValueCol.Get(i));
            }

        }

        private void ShowSelf()
        {
            this.Visible = true;
        }
        private void InputButton_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "Select input folder path";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string foldPath = dialog.SelectedPath;
                InputTextBox.Text = foldPath;
                checkPath = foldPath;
            }
        }

        private void OutButton_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "Select output folder path";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string folderPath = dialog.SelectedPath;
                OutTextBox.Text = folderPath;
                savePath = folderPath;
                if (System.IO.Directory.Exists(savePath))
                    savePath += "out.xlsx";
            }
        }

        private void checkCondition()
        {
            selectLanguage = SelectlanguageComboBox.SelectedIndex;
        }
        private void CheckGoogleTrans()
        {
            translateLanguage = Tools.languageSymbol[SelectTranslateComboBox.SelectedIndex];            
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if(objThread != null)
                objThread.Abort();
            EventCenter.RemoveListener(EGameEvent.eBackMainWindow,ShowSelf);
        }
        private void Reset()
        {
            conditionCsharp = false;
            conditionJava = false;
            conditionLua = false;
            conditionPython = false;
            conditionC = false;
            conditionCpp = false;
            conditionH = false;
            conditionHpp = false;
            conditionM = false;
            conditionMM = false;
        }
        private void buttonOk_Click(object sender, EventArgs e)
        {
            if (!CsharpCheckBox.Checked
                && !CppCheckBox.Checked
                && !JavaCheckBox.Checked
                && !LuaCheckBox.Checked
                && !PythonCheckBox.Checked
                && !CCheckBox.Checked)
            {
                MessageBox.Show("You have to choose at least one language","ERROR");
                return;
            }
            if(checkPath.Trim() == "")
            {
                MessageBox.Show("You have to choose one fold", "ERROR");
                return;
            }
            objThread = new Thread(new ThreadStart(delegate {
                bool isFinished = false;
                this.BeginInvoke(new System.Threading.ThreadStart(delegate ()
                {
                    CheckGoogleTrans();
                    checkCondition();

                    isContinueWriteExcel = false;
                    pageList.Clear();
                    _data.Clear();
                    List<FileInformation> list = DirectoryAllFiles.GetAllFiles(new System.IO.DirectoryInfo(checkPath));
                    foreach (var item in list)
                    {
                        pageStruct pageEntity = new pageStruct();
                        int lastStrPos = item.FileName.LastIndexOf(".");
                        if (lastStrPos < 0)
                            continue;
                        string lastStr = item.FileName.Substring(lastStrPos, item.FileName.Length - lastStrPos);
                        Reset();
                        if (CsharpCheckBox.Checked)
                            conditionCsharp = conditionCsharp || (lastStr.Trim().ToLower() == ".cs");
                        if (CppCheckBox.Checked)
                            conditionCpp = conditionCpp || (lastStr.Trim().ToLower() == ".cpp");
                        if (JavaCheckBox.Checked)
                            conditionJava = conditionJava || (lastStr.Trim().ToLower() == ".java");
                        if (LuaCheckBox.Checked)
                            conditionLua = conditionLua || (lastStr.Trim().ToLower() == ".lua");
                        if (PythonCheckBox.Checked)
                            conditionPython = conditionPython || (lastStr.Trim().ToLower() == ".py");
                        if (CCheckBox.Checked)
                            conditionC = conditionC || (lastStr.Trim().ToLower() == ".c");
                        if (HeaderHCheckBox.Checked)
                            conditionH = conditionH || (lastStr.Trim().ToLower() == ".h");
                        if (HeaderHppCheckBox.Checked)
                            conditionHpp = conditionHpp || (lastStr.Trim().ToLower() == ".hpp");
                        if (ObjectCCheckBox.Checked)
                            conditionM = conditionM || (lastStr.Trim().ToLower() == ".m");
                        if (ObjectCppCheckBox.Checked)
                            conditionMM = conditionMM || (lastStr.Trim().ToLower() == ".mm");

                        if (conditionCsharp
                            || conditionJava
                            || conditionLua
                            || conditionPython
                            || conditionC
                            || conditionCpp
                            || conditionH
                            || conditionHpp
                            || conditionM
                            || conditionMM)
                        {
                            ReadFile(item.FilePath);
                            if (_data.Count == 0)
                                continue;
                            showTextBox.AppendText("Processing file:" + item.FileName + "\n");
                            _data.ForEach(m => pageEntity.content.Add(m));
                            pageEntity.pageName = item.FileName;
                            pageEntity.pagePath = item.FilePath;
                            pageList.Add(pageEntity);
                        }
                        Thread.Sleep(50);
                    }
                    isFinished = true;
                    if (pageList.Count == 0)
                    {
                        showTextBox.Clear();
                        showTextBox.AppendText("Nothing to do...");
                        return;
                    }
                    showTextBox.AppendText("Start writing to Excel...\n");
                    
                }));
                while(!isFinished)
                    Thread.Sleep(50);
                WriteExcel(pageList, isContinueWriteExcel);
               
            }));


            objThread.Start();

        }
        #region//WriteExcel
        private void WriteExcel(List<pageStruct> pages,bool isContinue)
        {
            if (pages.Count == 0)
                return;
            DataTable dt = new DataTable();
            dt.Columns.Add("Word", typeof(string));
            dt.Columns.Add("Translate", typeof(string));
            dt.Columns.Add("Complete", typeof(string));
            dt.Columns.Add("File", typeof(string));
            dt.Columns.Add("Line", typeof(string));
            dt.Columns.Add("FilePath", typeof(string));
            
            foreach (var page in pages)
            {
                foreach(var line in page.content)
                {
                    DataRow dr = dt.NewRow();
                    dr["Word"] = line.lineWord.ToString();
                    if (translateLanguage.Trim() != "" && translateLanguage.Trim().ToLower() != "none")
                    {
                        dr["Translate"] = googleTranslate.GoogleTranslate(line.lineWord.ToString(), "auto", translateLanguage);
                        if(showTextBox.InvokeRequired)
                        {
                            showTextBox.Invoke((Action)delegate ()
                            {
                                MethodCompleted(line, dr["Translate"].ToString());
                            });
                        }
                           
                    }
                    else
                        dr["Translate"] = "";
                    dr["File"] = page.pageName;
                    dr["Complete"] = line.lineAll;
                    dr["Line"] = line.line;
                    dr["FilePath"] = page.pagePath;
                    dt.Rows.Add(dr);
                    dt.AcceptChanges();
                }
            }
            ExcelOperate.ExportExcel(dt,savePath, isContinue);
        }
        #endregion
        private void MethodCompleted(lineStruct line,string dr)
        {
            showTextBox.AppendText("Google Translate:" + line.lineWord.ToString() + " => " + dr + "\n");
        }


        private  void ReadFile(string filepath)
        {
            _data.Clear();
            using (StreamReader sr = new StreamReader(filepath))
            {
                string line;
                int pos = 0;
                while ((line = sr.ReadLine()) != null)
                {
                    if (Tools.HasLanguage(line,selectLanguage))
                    {
                        lineStruct lineEntity = new lineStruct();
                        lineEntity.lineWord = ExtractString(line).ToString();
                        lineEntity.line = pos;
                        lineEntity.lineAll = line;
                        _data.Add(lineEntity);
                    }
                    pos++;

                }
                sr.Close();
                sr.Dispose();
            }
            
        }

       
        private string DoubleQuotationMarks(string lineWord)
        {
            string result = "";
            int posBegin = lineWord.IndexOf("\"");
            if (posBegin < 0)
                return result;
            int posEnd = lineWord.LastIndexOf("\"");
            if(posEnd < 0)
                return result;
            if (posEnd - posBegin < 0)
                return lineWord;
            if (posEnd - posBegin == 0)
                return result;
            result = lineWord.Substring(posBegin, posEnd + 1 - posBegin);
            
            result = result.Trim();
            if (!Tools.HasLanguage(result, selectLanguage))
            {
                result = "";
            }
             return result;
        }

        private string ExplanatoryNote(string lineWord)
        {
            //             string result = "";
            //             int posBegin = lineWord.IndexOf(";");
            //             if (posBegin < 0)
            //                 posBegin = lineWord.IndexOf("//");
            //             if (posBegin < 0)
            //                 return result;
            //             if (lineWord.Length - 1 - posBegin == 0)
            //                 return result;
            //             result = lineWord.Substring(posBegin, lineWord.Length +1 - posBegin);

            string result = "";
            int posBegin = lineWord.IndexOf("//");
            if (posBegin < 0)
                return result;
            if (lineWord.Length - posBegin == 0)
                return result;
            result = lineWord.Substring(posBegin, lineWord.Length - posBegin);
            if (!Tools.HasLanguage(result, selectLanguage))
            {
                result = "";
            }
            return result;
        }
        private void RegionTest(ref string line)
        {
            if(line.Contains("#region"))
            {
                line = line.Trim();
                string subStr = line.Substring(0, 7);
                if(subStr == "#region")
                {
                    line = line.Substring(8, line.Length - 8);
                }
            }
        }
        private StringBuilder ExtractString(string lineWord)
        {
            wordListBuilder.Clear();
            //如果只要提取文字，不管符号
            //             Regex reg = new Regex(Tools.language);
            //             foreach (Match v in reg.Matches(lineWord))
            //                 wordListBuilder.Append(v.ToString());
            //如果直接取一行
            //  wordListBuilder.Append(lineWord.Trim());

            string contentStr = DoubleQuotationMarks(lineWord);
            string explanatoryStr = ExplanatoryNote(lineWord);
            if (contentStr.Trim() != "" && explanatoryStr.Trim() != "")
            {
                if (explanatoryStr.Contains(explanatoryStr))
                {
                    wordListBuilder.Append(explanatoryStr);
                }
                else
                {
                    wordListBuilder.Append(lineWord);
                    //     wordListBuilder.Append(contentStr.Trim() + "###" + explanatoryStr.Trim());
                }
            }

            else if (contentStr.Trim() != "")
                wordListBuilder.Append(contentStr.Trim());
            else if (explanatoryStr.Trim() != "")
                wordListBuilder.Append(explanatoryStr.Trim());
            else
            {
                RegionTest(ref lineWord);
                wordListBuilder.Append(lineWord.Trim());
            }

            return wordListBuilder;
        }

        private void SelectLanguageButton_Click(object sender, EventArgs e)
        {
            SelecltLanguagePanel.Visible = true;
        }

        private void OkButton_Click(object sender, EventArgs e)
        {
            SelecltLanguagePanel.Visible = false;
        }

        private void ImportButton_Click(object sender, EventArgs e)
        {
            ImportWindow window = new ImportWindow();
            window.StartPosition = FormStartPosition.CenterScreen;
            window.Visible = true;
            this.Visible = false;
        }
    }
}
